// // ThreadPool.hpp
// #pragma once

// #include <string>
// #include <queue>
// #include <vector>
// #include <pthread.h>
// #include <functional>
// #include "Thread.hpp"
// #include "Log.hpp"
// #include "LockGuard.hpp"

// using namespace std;

// // 默认线程数量
// const int default_threadnum = 3;

// class ThreadDate
// {
// public:
//     ThreadDate(const string &name)
//         : threadname(name)
//     {
//     }
//     ~ThreadDate()
//     {
//     }

// public:
//     string threadname;
// };

// template <class T>
// class ThreadPool
// {
// private:
//     ThreadPool(int num = default_threadnum)
//         : _threadnum(num)
//     {
//         // 初始化锁和条件变量
//         pthread_mutex_init(&_mutex, nullptr);
//         pthread_cond_init(&_cond, nullptr);

//         // 创建线程
//         for (int i = 0; i < _threadnum; i++)
//         {
//             string threadname = "thread-" + to_string(i + 1);
//             ThreadDate td(threadname);
//             // 由于Thread执行的是线程池的类内函数，而Thread调用的函数中并没有this指针
//             // 所以这里就使用bind函数，调整一下Thread调用函数的参数，使函数可以多接收一个参数
//             _threads.push_back(Thread<ThreadDate>(threadname, bind(&ThreadPool<T>::ThreadRun, this, placeholders::_1), td));
//             log.LogMessage(Info, "%s is create\n", threadname.c_str());
//         }
//     }

//     ThreadPool(const ThreadPool<T>& tp) = delete;
//     ThreadPool<T>& operator=(const ThreadPool<T>& tp) = delete;
// public:
//     static ThreadPool<T>* GetInstance(int num = default_threadnum)
//     {
//         if(instance == nullptr)
//         {
//             LockGuard lockguard(&_instance_mutex);
//             if(instance == nullptr)
//             {
//                 instance = new ThreadPool<T>();
//             }
//         }

//         return instance;
//     }

//     // 启动所有线程
//     bool Start()
//     {
//         for (auto &t : _threads)
//         {
//             t.Start();
//             log.LogMessage(Info, "%s , is running...\n", t.ThreadName().c_str());
//         }

//         return true;
//     }

//     // 等待所有线程终止
//     void Join()
//     {
//         for (auto &t : _threads)
//         {
//             t.Join();
//         }
//     }

// 	// 线程等待当前条件变量
//     void Thread_Wait(const ThreadDate &td)
//     {
//         pthread_cond_wait(&_cond, &_mutex);
//         log.LogMessage(Debug, "no task , %s is sleeping...\n", td.threadname.c_str());
//     }

// 	// 唤醒当前条件变量下的某个线程
//     void Thread_Wakeup()
//     {
//         pthread_cond_signal(&_cond);
//     }

// 	// 添加任务
//     bool Push(T &in)
//     {
//         LockGuard lockguard(&_mutex);
//         _q.push(in);
//         Thread_Wakeup();
//         log.LogMessage(Debug, "other thread push a task , task is %s\n", in.PrintTask().c_str());

//         return true;
//     }

// 	// 线程需要执行的回调函数
//     void ThreadRun(const ThreadDate &td)
//     {
//         while (1)
//         {
//             T t;

//             // 取任务
//             {
//                 LockGuard lockguard(&_mutex);

//                 while (_q.empty())
//                 {
//                     Thread_Wait(td);
//                     log.LogMessage(Debug, "haven task , %s is wakeup\n", td.threadname.c_str());
//                 }
//                 t = _q.front();
//                 _q.pop();
//             }
//             // 执行任务
//             t.Run();
//             log.LogMessage(Debug, "%s handler task %s done , result is %s\n",
//                            td.threadname.c_str(), t.PrintTask().c_str(), t.PrintResult().c_str());
//         }
//     }

// 	// 销毁锁和条件变量
//     ~ThreadPool()
//     {
//         pthread_mutex_destroy(&_mutex);
//         pthread_cond_destroy(&_cond);
//     }

// private:
//     queue<T> _q;
//     vector<Thread<ThreadDate>> _threads;
//     int _threadnum;

//     pthread_mutex_t _mutex;
//     pthread_cond_t _cond;

//     static ThreadPool<T>* instance;
//     static pthread_mutex_t _instance_mutex;
// };

// template<class T>
// ThreadPool<T>* ThreadPool<T>::instance = nullptr;
// template<class T>
// pthread_mutex_t ThreadPool<T>::_instance_mutex = PTHREAD_MUTEX_INITIALIZER;

// ThreadPool.hpp
#pragma once

#include <string>
#include <queue>
#include <vector>
#include <pthread.h>
#include <functional>
#include "Thread.hpp"
#include "Log.hpp"
#include "LockGuard.hpp"

using namespace std;

const int default_threadnum = 3;

class ThreadDate
{
public:
    ThreadDate(const string &name)
        : threadname(name)
    {
    }
    ~ThreadDate()
    {
    }

public:
    string threadname;
};

template <class T>
class ThreadPool
{
public:
    ThreadPool(int num = default_threadnum)
        : _threadnum(num)
    {
        // 初始化锁和条件变量
        pthread_mutex_init(&_mutex, nullptr);
        pthread_cond_init(&_cond, nullptr);

        // 创建线程
        for (int i = 0; i < _threadnum; i++)
        {
            string threadname = "thread-" + to_string(i + 1);
            ThreadDate td(threadname);
            // 由于Thread执行的是线程池的类内函数，而Thread调用的函数中并没有this指针
            // 所以这里就使用bind函数，调整一下Thread调用函数的参数，使函数可以多接收一个参数
            _threads.push_back(Thread<ThreadDate>(threadname, bind(&ThreadPool<T>::ThreadRun, this, placeholders::_1), td));
            log.LogMessage(Info, "%s is create\n", threadname.c_str());
        }
    }
    
	// 启动所有线程
    bool Start()
    {
        for (auto &t : _threads)
        {
            t.Start();
            log.LogMessage(Info, "%s , is running...\n", t.ThreadName().c_str());
        }

        return true;
    }

	// 等待所有线程终止
    void Join()
    {
        for (auto &t : _threads)
        {
            t.Join();
        }
    }

	// 线程等待当前条件变量
    void Thread_Wait(const ThreadDate &td)
    {
        pthread_cond_wait(&_cond, &_mutex);
        log.LogMessage(Debug, "no task , %s is sleeping...\n", td.threadname.c_str());
    }

	// 唤醒当前条件变量下的某个线程
    void Thread_Wakeup()
    {
        pthread_cond_signal(&_cond);
    }

	// 添加任务
    bool Push(T &in)
    {
        LockGuard lockguard(&_mutex);
        _q.push(in);
        Thread_Wakeup();
        log.LogMessage(Debug, "other thread push a task , task is %s\n", in.PrintTask().c_str());

        return true;
    }

	// 线程需要执行的回调函数
    void ThreadRun(const ThreadDate &td)
    {
        while (1)
        {
            T t;

            // 取任务
            {
                LockGuard lockguard(&_mutex);

                while (_q.empty())
                {
                    Thread_Wait(td);
                    log.LogMessage(Debug, "haven task , %s is wakeup\n", td.threadname.c_str());
                }
                t = _q.front();
                _q.pop();
            }
            // 执行任务
            t.Run();
            log.LogMessage(Debug, "%s handler task %s done , result is %s\n",
                           td.threadname.c_str(), t.PrintTask().c_str(), t.PrintResult().c_str());
        }
    }

	// 销毁锁和条件变量
    ~ThreadPool()
    {
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_cond);
    }

private:
    queue<T> _q;
    vector<Thread<ThreadDate>> _threads;
    int _threadnum;

    pthread_mutex_t _mutex;
    pthread_cond_t _cond;
};